package main

import "fmt"

// 用于在函数返回之前执行一些清理或回调操作，
// 1.执行顺序：根据定义的顺序，从后往前执行
// 2.执行时机，方法内的函数执行完，方法返回前，类似于java 的 finally
func main() {
	d6_test01()

	d6_test02()

	fmt.Println("done，666，")
}

func d6_test01() {
	defer fmt.Println("第一个 defer")
	defer fmt.Println("第二个 defer")
	fmt.Println("Hello, World!")
	defer fmt.Println("第三个 defer")
	defer fmt.Println("第四个 defer")
}

func d6_test02() (err error) {
	// 捕获d6_test02的异常
	defer d6_recoverWrapper(&err)

	defer fmt.Println("1，有异常依旧执行")
	panic("这里抛出了异常")
	defer fmt.Println("2，有异常，这里无法执行了。因为没有执行到这里，还没有注册监听")
	return nil
}

// 封装的公共函数，用于捕获并处理panic异常
func d6_recoverWrapper(err *error) {
	switch p := recover(); p {
	case nil: // no panic
		*err = fmt.Errorf("空指针异常")
	default:
		*err = fmt.Errorf("internal error: %v", p)
	}
}
